<?php
//DB作为一个数据库操作类，一切增删查改核心操作皆在此类，因此该类将会被完全封装，而是用model类来进行和外界通信
class DB {
    protected $pdo = null;         //用来和pdo类进行组合，由于pdo的构造方法是public，因此这里不能是用继承的方法private构造函数
    private static $instance = null;
    private $showSql = '';       //用来展示构建得sql
    private function __clone() {}

    protected static function getDB() {
        if(!self::$instance instanceof self) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    private function __construct() {
        try {
            //pdo配置
            $this->pdo = new PDO(DB_DNS,DB_USER,DB_PASS,array(PDO::MYSQL_ATTR_INIT_COMMAND=>'SET NAMES '.DB_CHARSET));
        } catch (PDOException $e) {
            exit('数据库连接失败!信息是'.$e->getMessage());
        }
    }

    //查询
    /*
     * @param Array $fields     需要查询的字段
     * @param Array $condition  查询的条件
     */
    protected function select($tables,$fields,Array $condition) {
        $where = $order = $limit = $like = $between = '';
        if(!Validate::isNullArray($condition)) {
            if(isset($condition['where'])) {
                foreach($condition['where'] as $key=>$value) {
                    $where .= $value.' ';
                }
                $where = 'WHERE '.$where;
            }
            if(isset($condition['like'])) {
                foreach($condition['like'] as $key=>$value) {
                    $like .= "WHERE $key LIKE '%$value%'";
                }
            }
            $limit = isset($condition['limit']) ? 'LIMIT '.$condition['limit'] : '';
            $order = isset($condition['order']) ? 'ORDER BY '.$condition['order'] : '';
        }
        $fields = implode(',',$fields);
        $table = isset($tables[1]) ? $tables[0].','.$tables[1] : $tables[0];
        $sql = "SELECT $fields FROM $table $where $like $order $limit";
        $this->showSql = $sql;
        $stmt = $this->execute($sql);
        $result = array();
        while(!!$objs = $stmt->fetchObject()) {
            $result[] = $objs;
        }
        return Tool::setHtmlString($result);
    }

    /*
     *  @needData Array 需要操作的字段和对应的值
     */
    protected function add($tables,$needData=array()) {
        //字段组
        $fieldsArray = array();
        //值组
        $valueArray = array();
        //分解字段和对应的值
        foreach($needData as $key=>$value) {
            $fieldsArray[] = $key;
            $valueArray[] = $value;
        }
        //使每个值加上一个分号
        //array_walk($valueArray,create_function('&$value,$key','$value="\'$value\'";')); 此方法效率过低，虽可行，但不推荐使用
        $fields = implode(',',$fieldsArray);
        $value = implode("','", $valueArray);
        //DB类负责与数据库进行实际操作
        $sql = "INSERT INTO $tables($fields) VALUES('$value')";
        $this->showSql = $sql;
        return $this->execute($sql)->rowCount();
    }

    protected function update($tables,Array $updateData,Array $condition) {
        $sCondition = '';
        foreach($condition as $key=>$value) {
            $sCondition .= $value.' AND ';
        }
        $sCondition = substr($sCondition,0,-4);
        $data = '';
        foreach($updateData as $key=>$value) {
            if(Validate::isArray($value)) {
                $data = $key.'='.$value[0].',';
            } else {
                $data .= $key.'=\''.$value.'\',';
            }
        }
        $data = substr($data,0,-1);
        $sql = "UPDATE $tables SET $data WHERE $sCondition";
        $this->showSql = $sql;
        return $this->execute($sql)->rowCount();
    }

    protected function delete($tables,Array $condition) {
        $limit = '';
        $rule = ' AND ';    //默认模式为and
        if(isset($condition['rule'])) {
            $rule = $condition['rule'] == 'and' ? ' AND ' : ' OR ';
        }
        if(isset($condition['limit'])) $limit = 'LIMIT '.$condition['limit'];
        $fullondition = '';
        foreach($condition as $key=>$value) {
            if(!Validate::isNumber($key)) continue;
            $fullondition .= $value.$rule;
        }
        $fullondition = substr($fullondition,0,-4);
        $sql = "DELETE FROM $tables WHERE $fullondition $limit";
        $this->showSql = $sql;
        return $this->execute($sql)->rowCount();
    }

    //验证数据的唯一性
    protected function isOne($tables,Array $condition) {
        $fullCondition = '';
        foreach($condition as $key=>$value) {
            if(!Validate::isNumber($key)) continue;
            $fullCondition .= $value.' AND ';
        }
        $fullCondition = substr($fullCondition,0,-4);
        $sql = "SELECT id FROM $tables WHERE $fullCondition LIMIT 1";
        $this->showSql = $sql;
        return $this->execute($sql)->rowCount();
    }

    //总记录条数
    protected function total($tables,$condition=array()) {
        $where = '';
        if(isset($condition['where']) && Validate::isArray($condition['where'])) {
            foreach($condition['where'] as $key=>$value) {
                $where .= 'WHERE '.$value.' AND ';
            }
        }
        $where = substr($where,0,-4);
        $sql = "SELECT COUNT(*) as count FROM $tables $where";
        $this->showSql = $sql;
        $stmt = $this->execute($sql);
        return $stmt->fetchObject()->count;
    }

    //获取下一条数据的id
    protected function nextId($tables) {
        $sql = "SHOW TABLE STATUS LIKE '$tables'";
        $this->showSql = $sql;
        $stmt = $this->execute($sql);
        return $stmt->fetchObject()->Auto_increment;
    }

    private function execute($sql) {
        try{
            $stmt = $this->pdo->prepare($sql);
            $stmt->execute();
        } catch(PDOException $e) {
            echo 'sql语句:'.$sql.'有错误,具体信息为'.$e->getMessage();
        }
        return $stmt;
    }

    //展示构建的sql
    public function showSql() {
        echo $this->showSql;
    }


}

?>